<?php

declare(strict_types=1);

namespace app\controller\system\settlement;

use app\BaseController;
use app\service\factory\ResponseFactory;
use app\service\settlement\InvoiceService;
use app\validate\settlement\InvoiceValidate;
use think\Response;
use Throwable;

class Invoice extends BaseController
{
    public function index(InvoiceService $invoiceService): Response
    {
        try {
            $page = max(1, (int) $this->request->param('page', 1));
            $pageSize = (int) $this->request->param('page_size', 20);
            $pageSize = $pageSize > 0 ? min($pageSize, 100) : 20;

            $filters = [
                'statement_id' => $this->request->param('statement_id'),
                'seller_org_id' => $this->request->param('seller_org_id'),
                'status' => $this->request->param('status'),
                'keyword' => $this->request->param('keyword'),
            ];

            $paginator = $invoiceService->paginate($filters, $page, $pageSize);
            $list = array_map(static fn($item) => $item->toArray(), $paginator->items());

            return json(ResponseFactory::paginated(
                $list,
                (int) $paginator->total(),
                $page,
                $pageSize
            ));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function read(int $id, InvoiceService $invoiceService): Response
    {
        try {
            $invoice = $invoiceService->get($id);
            return json(ResponseFactory::success($invoice->toArray()));
        } catch (Throwable $e) {
            $code = $e->getCode() ?: 500;
            if ($code >= 600 || $code < 100) {
                $code = 500;
            }
            return json(ResponseFactory::error($e->getMessage(), $code));
        }
    }

    public function save(InvoiceService $invoiceService): Response
    {
        try {
            $userId = (int) ($this->request->user_id ?? 0);
            if ($userId <= 0) {
                return json(ResponseFactory::error('未登录或缺少用户信息', 401));
            }

            $payload = $this->request->post();
            $this->validate($payload, InvoiceValidate::class . '.create');

            $invoice = $invoiceService->create($payload);

            return json(ResponseFactory::success($invoice->toArray(), '发票已提交'));
        } catch (Throwable $e) {
            $code = $e->getCode() ?: 500;
            if ($code >= 600 || $code < 100) {
                $code = 500;
            }
            return json(ResponseFactory::error($e->getMessage(), $code));
        }
    }

    public function update(int $id, InvoiceService $invoiceService): Response
    {
        try {
            $userId = (int) ($this->request->user_id ?? 0);
            if ($userId <= 0) {
                return json(ResponseFactory::error('未登录或缺少用户信息', 401));
            }

            $payload = $this->request->put();
            $this->validate($payload, InvoiceValidate::class . '.update');

            $invoice = $invoiceService->get($id);
            $updated = $invoiceService->update($invoice, $payload, $userId);

            return json(ResponseFactory::success($updated->toArray(), '发票已更新'));
        } catch (Throwable $e) {
            $code = $e->getCode() ?: 500;
            if ($code >= 600 || $code < 100) {
                $code = 500;
            }
            return json(ResponseFactory::error($e->getMessage(), $code));
        }
    }
}
